AssumeRoleで取得した一時クレデンシャルの情報を環境変数にセットしてもAWS認証が通らずハマった話
こんにちは、CX事業本部の若槻です。
前回投稿した次の記事の執筆のための検証の際に、
記事で紹介しているワンライナーにより取得した一時クレデンシャルの情報を環境変数にセットしてもAWS認証が通らずハマったので、その際の話を共有します。
事象
前述の記事で紹介している次のコマンドを実行して、AssumeRoleで取得した一時クレデンシャルの情報をを環境変数AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
およびAWS_SESSION_TOKEN
にセットしました。
% target_profile=<Assume先プロファイル名> % mfa_code=<6桁のMFAコード> % AWS_STS_CREDENTIALS=`aws sts assume-role --profile default --role-arn $(aws configure get ${target_profile}.role_arn) --role-session-name ${target_profile}-session --serial-number $(aws configure get ${target_profile}.mfa_serial) --token-code $mfa_code`;export AWS_ACCESS_KEY_ID=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.AccessKeyId'`;export AWS_SECRET_ACCESS_KEY=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SecretAccessKey'`;export AWS_SESSION_TOKEN=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SessionToken'`
しかしAWS CLIコマンドを実行すると次のようにThe provided token has expired.
とトークン期限切れのエラーとなりAWS認証が通りません。
% aws sts get-caller-identity An error occurred (ExpiredToken) when calling the GetCallerIdentity operation: The provided token has expired.
原因・解決
原因は、環境変数AWS_SECURITY_TOKEN
に古い一時クレデンシャルの情報が残っていたことでした。
環境変数を確認すると、ワンライナーによりセットされたAWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
およびAWS_SESSION_TOKEN
に加えて、AWS_SECURITY_TOKEN
が定義され値にAWS_SESSION_TOKEN
と異なるトークン値がセットされていました。
% printenv | grep AWS AWS_VAULT=xxxxxxxxxx AWS_DEFAULT_REGION=ap-northeast-1 AWS_REGION=ap-northeast-1 AWS_SECURITY_TOKEN=XXXXXXX//////////XXXXXXXXXXXXXXX AWS_SESSION_EXPIRATION=2020-09-05T09:06:10Z AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXX AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYY AWS_SESSION_TOKEN=YYYYYYYYYYYYY//////////YYYYYYYYYYYYYY==
このAWS_SECURITY_TOKEN
は、記事執筆前に別件でaws-vault(サードパーティのAWS向け認証管理ツール)による一時クレデンシャルの取得を行った際にセットされていたものでした。ドキュメントにある通り、aws-vaultの動作仕様として一時クレデンシャルのトークン値を環境変数AWS_SESSION_TOKEN
とAWS_SECURITY_TOKEN
の双方にセットされていたようです。
その状態でAWS_SESSION_TOKEN
の方にのみワンライナーで新しいトークン値をセットしても、AWS CLIコマンドがAWS_SECURITY_TOKEN
の方のトークン値を優先して参照してしまったため実行がトークン期限切れエラーとなったようです。
AWS_SECURITY_TOKEN
をクリアするとAWS CLIコマンドはエラー無く実行できるようになりました。
% unset AWS_SECURITY_TOKEN
AWS_SESSION_TOKEN
とAWS_SECURITY_TOKEN
の違いは?
事象の原因と解決方法は分かりましたが、そもそもなんでトークン値の取得先がAWS_SESSION_TOKEN
とAWS_SECURITY_TOKEN
の2つもあるの?それぞれの使い分けは?というのが気になり調べてみると次のような記事を見つけました。
- What is the “aws_security_token” used for | stackoverflow
- A New and Standardized Way to Manage Credentials in the AWS SDKs | AWS Security Blog
もともとAWSアクセス時の認証トークンの取得先にはAWS_SESSION_TOKEN
とAWS_SECURITY_TOKEN
のいずれかもしくは両方が使われていましたが、その仕様はSDKごとにバラバラだったようです。
それが2014年にほぼ全てのSDKは認証トークンをAWS_SESSION_TOKEN
から取得するように統一されましたが、それまで使用されていたAWS_SECURITY_TOKEN
からも取得できる仕様は残されていたようです。
aws-vaultが両方の環境変数にセットするようになっているのは、そのような歴史的経緯により生まれたAWS側の仕様に対応するためだったんですね。
おわりに
AssumeRoleで取得した一時クレデンシャルの情報を環境変数にセットしてもAWS認証が通らずハマった話のご紹介でした。
教訓としては、きちんと環境変数をクリアする癖をつけたり、認証ツールを統一したりするようにしましょう。
参考
- 環境変数の一覧を表示するには | @IT
- What is the “aws_security_token” used for | stackoverflow
- A New and Standardized Way to Manage Credentials in the AWS SDKs | AWS Security Blog
以上